﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Threading;
using System.Configuration;
using System.IO;
using System.Net;

namespace WeatherService
{
    public class WeatherBLL
    {
        private static int interval = Convert.ToInt32(ConfigurationManager.AppSettings["Interval"]) * 1000;
        private static string strKey = "d75e3cd9add17da9c348c3bc6e98936b";
        DataSet m_ds = null;
        public WeatherBLL()
        {
        }

        public void MainProcess(bool flag)
        {
            int hour = 0;
            bool bolSwitch = true;
            while (flag)
            {
                try
                {
                    if (m_ds == null) //第一次连接数据库
                    {
                        m_ds = GetList();
                    }
                }
                catch (Exception ex)
                {
                    WriteLog(ex.Message);
                    //休眠时长10分钟
                    Thread.Sleep(interval*2*6*10);
                    continue;
                }
                
                if (bolSwitch == true || hour == DateTime.Now.Hour)
                {
                    bolSwitch = false;
                    hour = DateTime.Now.Hour;
                    if (DateTime.Now.Minute > 10) //每小时十分执行获取数据更新
                    {
                        if (!Exists(hour))
                        {
                            BeginExe(m_ds, ref hour);
                        }
                        else
                        {
                            if (hour == 23)
                            {
                                hour = 0;
                            }
                            else
                            {
                                hour = DateTime.Now.Hour + 1;
                            }
                        }
                    }
                }

                //休眠时长,默认10s
                if (Thread.CurrentThread.IsAlive)
                {
                    Thread.Sleep(interval);
                }
            }
        }

        public void BeginExe(DataSet ds, ref int hour)
        {
            string strAreaIds = string.Empty;
            for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
            {
                strAreaIds = strAreaIds + ds.Tables[0].Rows[i]["areaId"].ToString() + "|";

                if ((i + 1) % 20 == 0 || (i + 1) == ds.Tables[0].Rows.Count)
                {
                    strAreaIds = strAreaIds.TrimEnd('|');
                    if (hour == 8 || hour == 12 || hour == 18)
                    {
                        GetForecast(strAreaIds, hour);
                    }
                    GetObserve(strAreaIds, hour);
                    strAreaIds = "";
                }
            }

            if (hour == 23)
            {
                hour = 0;
            }
            else
            {
                hour = DateTime.Now.Hour + 1;
            }
        }

        /// <summary>
        /// 获取预报数据
        /// </summary>
        /// <param name="areaIds">站点ID</param>
        /// <param name="hour">小时</param>
        public void GetForecast(string areaIds, int hour)
        {
            try
            {
                string strDataType = "1001001"; //大类编号
                int intSequence = 0;
                string strForecast = "forecast"; //预报
                string strForecastUrl = string.Format(@"http://api.weatherdt.com/common/?area={0}&type={1}&key={2}", areaIds, strForecast, strKey);
                string strJson = SendHttpRequest(strForecastUrl);
                if (strJson.Length > 10)
                {
                    var obj = Newtonsoft.Json.Linq.JObject.Parse(strJson);
                    string[] areaIdList = areaIds.Split('|');
                    string strDataValue = string.Empty;
                    List<string> list = new List<string>();
                    for (int i = 0; i < areaIdList.Length; i++)
                    {
                        try
                        {
                            var objData = obj["" + strForecast + ""]["24h"]["" + areaIdList[i].ToString() + ""]["" + strDataType + ""];
                            string requestDate = obj["" + strForecast + ""]["24h"]["" + areaIdList[i].ToString() + ""]["000"].ToString();
                            DateTime dt = DateTime.ParseExact(requestDate, "yyyyMMddHHmm", System.Globalization.CultureInfo.CurrentCulture);
                            requestDate = dt.ToString();
                            for (int j = 0; j < 4; j++)
                            {
                                strDataValue = objData[j].ToString().Replace("\r\n", "").Replace(" ", "");
                                intSequence = j + 1;
                                string insertSql = string.Format(@"INSERT INTO w_dt_weatherData(areaId,bigDataType,dataValue,sequence,refreshRate,requestDate,createDate) VALUES('{0}','{1}','{2}',{3},{4},'{5}',GETDATE())", areaIdList[i].ToString(), strDataType, strDataValue, intSequence, hour, requestDate);
                                list.Add(insertSql);
                            }
                        }
                        catch (Exception ex)
                        {
                            WriteLog(areaIdList[i].ToString() + "|forecast|" + strJson + "|" + ex.Message, "Api");
                            continue;
                        }
                    }
                    DbHelperSQL.ExecuteSqlTran(list);
                }
                else
                {
                    WriteLog(strJson, "Api");
                }
            }
            catch (Exception ex)
            {
                WriteLog(ex.Message);
            }
        }

        /// <summary>
        /// 获取实况数据
        /// </summary>
        /// <param name="areaIds">站点ID</param>
        /// <param name="hour">小时</param>
        public void GetObserve(string areaIds, int hour)
        {
            try
            {
                string strDataType = "1001002"; //大类编号
                int intSequence = 0;
                string strObserve = "observe"; //实况
                string strObserveUrl = string.Format(@"http://api.weatherdt.com/common/?area={0}&type={1}&key={2}", areaIds, strObserve, strKey);
                string strJson = SendHttpRequest(strObserveUrl);
                if (strJson.Length > 10)
                {
                    var obj = Newtonsoft.Json.Linq.JObject.Parse(strJson);
                    string[] areaIdList = areaIds.Split('|');
                    string strDataValue = string.Empty;
                    string insertSql = string.Empty;
                    List<string> list = new List<string>();
                    for (int i = 0; i < areaIdList.Length; i++)
                    {
                        try
                        {
                            strDataValue = obj["" + strObserve + ""]["" + areaIdList[i].ToString() + ""]["" + strDataType + ""].ToString().Replace("\r\n", "").Replace(" ", "");
                            insertSql = string.Format(@"INSERT INTO w_dt_weatherData(areaId,bigDataType,dataValue,sequence,refreshRate,createDate) VALUES('{0}','{1}','{2}',{3},{4},GETDATE())", areaIdList[i].ToString(), strDataType, strDataValue, intSequence, hour);
                            list.Add(insertSql);
                        }
                        catch (Exception ex)
                        {
                            WriteLog(areaIdList[i].ToString() + "|observe|" + strJson + "|" + ex.Message, "Api");
                            continue;
                        }
                    }
                    DbHelperSQL.ExecuteSqlTran(list);
                }
                else
                {
                    WriteLog(strJson, "Api");
                }
            }
            catch (Exception ex)
            {
                WriteLog(ex.Message);
            }
        }
        
        /// <summary>
		/// 获得数据列表
		/// </summary>
		public DataSet GetList()
        {
            StringBuilder strSql = new StringBuilder();
            strSql.Append("SELECT areaId FROM w_dt_citys WHERE parentId<>0 ");
            DataSet ds = DbHelperSQL.Query(strSql.ToString());
            return ds;
        }

        /// <summary>
        /// 判断服务启动时是否存在当前小时的数据
        /// </summary>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <param name="hour">当前小时</param>
        /// <returns></returns>
        public bool Exists(int hour)
        {
            string strStartTime = DateTime.Now.ToString("yy-MM-dd");
            string strEndTime = DateTime.Now.AddDays(1).ToString("yy-MM-dd");
            string strSql = string.Format(@"SELECT COUNT(1) FROM [km_platform].[dbo].[w_dt_weatherData] WHERE createDate>='{0}' AND createDate<'{1}' AND refreshRate={2}", strStartTime, strEndTime, hour);
            return DbHelperSQL.Exists(strSql);
        }


        public string SendHttpRequest(string pUrl)
        {
            Uri httpURL = new Uri(pUrl, true);
            HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(httpURL);
            HttpWebResponse httpResp = (HttpWebResponse)httpReq.GetResponse();
            Stream respStream = httpResp.GetResponseStream();
            StreamReader respStreamReader = new StreamReader(respStream, Encoding.UTF8);
            string jsonContent = respStreamReader.ReadToEnd();
            respStreamReader.Close();
            respStream.Close();
            httpResp.Close();

            return jsonContent;
        }

        /// <summary>
        /// 输出日志
        /// </summary>
        /// <param name="strMemo">日志内容</param>
        /// <param name="tag">标签，用于检索日志时方便进行过滤</param>
        /// <param name="type">类型 : Ex 系统异常 Api 请求响应错误码</param>
        public void WriteLog(string strMemo, string type = "Ex", string tag = "Error")
        {
            try
            {
                var sb = new StringBuilder();
                sb.AppendLine("----------------------------------------------------------");
                sb.AppendLine(string.Format("{0}：{2}:{1},{1:fffff}", type, DateTime.Now, tag));
                sb.AppendLine("----------------------------------------------------------");
                sb.AppendLine(strMemo);
                sb.AppendLine("=END=LOG==================================================");

                var filename = Directory.GetCurrentDirectory() + "\\" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
                lock (filename)
                {
                    //临时锁定
                    using (
                        var sr = !System.IO.File.Exists(filename)
                            ? System.IO.File.CreateText(filename)
                            : System.IO.File.AppendText(filename))
                    {
                        sr.WriteLineAsync(sb.ToString());
                    }
                }
            }
            catch
            {}
        }
    }
}
